#include "stdafx.h"
#include "ILUAScript.h"
#include "stdlib.h"
extern "C"
{
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
ILUADraw*g_draw = NULL;

namespace str
{
	const wchar_t* a2w_1(const char*ss)
	{
		static wchar_t buf[4096] = { 0 };
		buf[0] = 0;
		int n = MultiByteToWideChar(CP_ACP, 0, ss, -1, buf, _countof(buf));
		if (n >= 0)
		{
			buf[n] = 0;
		}
		return buf;
	}
}
namespace func
{
	void MsgBox(const TCHAR*str)
	{
		MessageBox(NULL, str, L"LUA", MB_OK|MB_ICONWARNING);
	}
	int window(lua_State*LS)//window(x,y,cx,cy,mode)
	{
		int num = lua_gettop(LS);
		if (num != 5)
		{
			MsgBox(L"window(x,y,cx,cy,mode)");
			return 0;
		}
		double vv[4];
		for (int i = 0; i < 4; ++i)
			vv[i] = lua_tonumber(LS, i + 1);
		int mode=lua_tonumber(LS, 5);
		g_draw->arch_window_rect(vv,mode);
		return 0;
	}
	int cylinder(lua_State*LS)//cylinder(x,y,z,x2,y2,z2,radius)
	{
		int num = lua_gettop(LS);
		if (num != 7)
		{
			MsgBox(L"cylinder(x,y,z,x2,y2,z2,radius)");
			return 0;
		}
		double vv[7];
		for (int i = 0; i < 7; ++i)
			vv[i] = lua_tonumber(LS, i + 1);
		g_draw->cylinder(vv,&vv[3],vv[6]);
		return 0;
	}
	int cube(lua_State*LS)//cube(x,y,z,xlen,ylen,zlen)
	{
		int num = lua_gettop(LS);
		if (num != 6)
		{
			MsgBox(L"cube(x,y,z,xlen,ylen,zlen)");
			return 0;
		}
		double cp[3];
		double sz[3];
		cp[0] = lua_tonumber(LS, 1);
		cp[1] = lua_tonumber(LS, 2);
		cp[2] = lua_tonumber(LS, 3);
		sz[0] = lua_tonumber(LS, 4);
		sz[1] = lua_tonumber(LS, 5);
		sz[2] = lua_tonumber(LS, 6);
		g_draw->cube(cp, sz);
		return 0;
	}
	int torus(lua_State*LS)//torus(x,y,z,nx,ny,nz,r1,r2)
	{
		int num = lua_gettop(LS);
		if (num != 8)
		{
			MsgBox(L"torus(x,y,z,nx,ny,nz,r1,r2)");
			return 0;
		}
		double vv[8];
		for (int i = 0; i < 8; ++i)
			vv[i] = lua_tonumber(LS, i + 1);
		g_draw->torus(vv, &vv[3], vv[6], vv[7]);
		return 0;
	}
	int window_hexagon(lua_State*LS)//window_hexagon(x,y,r)
	{
		int num = lua_gettop(LS);
		if (num != 3)
		{
			MsgBox(L"window_hexagon(x,y,r)");
			return 0;
		}
		double vv[3];
		for (int i = 0; i < 3; ++i)
			vv[i] = lua_tonumber(LS, i + 1);
		g_draw->arch_window_hexagon(vv);
		return 0;
	}
	int window_circle(lua_State*LS)//window_circle(x,y,r)
	{
		int num = lua_gettop(LS);
		if (num != 3)
		{
			MsgBox(L"window_circle(x,y,r)");
			return 0;
		}
		double vv[3];
		for (int i = 0; i < 3; ++i)
			vv[i] = lua_tonumber(LS, i + 1);
		g_draw->arch_window_circle(vv);
		return 0;
	}
	int window_pentagon(lua_State*LS)//window_pentagon(x,y,r)
	{
		int num = lua_gettop(LS);
		if (num != 3)
		{
			MsgBox(L"window_pentagon(x,y,r)");
			return 0;
		}
		double vv[3];
		for (int i = 0; i < 3; ++i)
			vv[i] = lua_tonumber(LS, i + 1);
		g_draw->arch_window_pentagon(vv);
		return 0;
	}
	int window_arc(lua_State*LS)//window_arc(x1,y1,x2,y2,x3,y3)
	{
		int num = lua_gettop(LS);
		if (num == 6)
		{
			double vv[6];
			for (int i = 0; i < 6; ++i)
				vv[i] = lua_tonumber(LS, i + 1);
			g_draw->arch_window_arc(6,vv);
			return 0;
		}
		else if (num == 5)
		{
			double vv[6];
			for (int i = 0; i < 5; ++i)
				vv[i] = lua_tonumber(LS, i + 1);
			g_draw->arch_window_arc(5,vv);
			return 0;
		}
		MsgBox(L"window_arc(x1,y1,x2,y2,x3,y3) or\r\n window_arc(x1,y1,x2,y2,chord_height)");
		return 0;
	}
	int sphere(lua_State*LS)//sphere(x,y,z,r)
	{
 		int num = lua_gettop(LS);
		if (num != 4)return 0;
		double cp[3];
		cp[0]=lua_tonumber(LS, 1);
		cp[1] = lua_tonumber(LS, 2);
		cp[2] = lua_tonumber(LS, 3);
		double r = lua_tonumber(LS, 4);
		g_draw->sphere(cp, r);
// 		double v = lua_tonumber(LS, -1);
// 		const char*ss = lua_tostring(LS, -1);
// 		lua_pop(LS, 1);
		return 0;
	}
}
class ILUAScript_imp
{
	lua_State*m_state;
public:
	ILUAScript_imp()
	{
// 		char buff[256];
// 		int error;
		m_state = luaL_newstate();   /* opens Lua */
		luaopen_base(m_state);       /* opens the basic library */
		luaopen_table(m_state);      /* opens the table library */
		luaopen_io(m_state);         /* opens the I/O library */
		luaopen_string(m_state);     /* opens the string lib. */
		luaopen_math(m_state);       /* opens the math lib. */
		//
		lua_register(m_state, "sphere", func::sphere);
		lua_register(m_state, "torus", func::torus);
		lua_register(m_state, "cube", func::cube);
		lua_register(m_state, "cylinder", func::cylinder);
		lua_register(m_state, "window", func::window);
		lua_register(m_state, "window_hexagon", func::window_hexagon);
		lua_register(m_state, "window_pentagon", func::window_pentagon);
		lua_register(m_state, "window_circle", func::window_circle);
		lua_register(m_state, "window_arc", func::window_arc);
	}
	~ILUAScript_imp()
	{
		lua_close(m_state);
	}
	void setGlobalVar(const char*varName, double v)
	{
		lua_pushnumber(m_state, v);
		lua_setglobal(m_state, varName);
	}
	bool run(const char*script, ILUADraw*draw)
	{
		g_draw = draw;
		int error=luaL_loadstring(m_state, script);
		if (error)
		{
			const char*err=lua_tostring(m_state, -1);
			::MessageBoxA(NULL, err, "LUA", MB_OK|MB_ICONWARNING);
			lua_pop(m_state, 1);
			return false;
		}
		lua_pcall(m_state, 0, 0, 0);
		return true;
	}
};
ILUAScript::ILUAScript()
{
	m_imp = new ILUAScript_imp;
}


ILUAScript::~ILUAScript()
{
	delete m_imp;
}

bool ILUAScript::run(const char*script, ILUADraw*draw)
{
	return  m_imp->run(script,draw);
}

void ILUAScript::setGlobalVar(const char*varName, double v)
{
	m_imp->setGlobalVar(varName, v);
}
